package com.ckm.aop;

import com.ckm.annotation.MongoDS;
import com.ckm.context.DynamicMongoContextHolder;
import com.ckm.processor.DynamicBeanProcessor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.AopContext;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@RequiredArgsConstructor
public class DynamicAnnotationInterceptor implements MethodInterceptor {
//InvocationHandler
//    private final DynamicBeanProcessor processor;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        DynamicMongoContextHolder.setMongoContext(invocation.getMethod().getAnnotation(MongoDS.class).value());
        try {
            return invocation.proceed();
        }finally {
            DynamicMongoContextHolder.pollMongoContext();
        }

    }

    private String findKey(MethodInvocation invocation){
//        System.out.println(AopContext.currentProxy().getClass().getName());
        Object current = AopContext.currentProxy();
        boolean aopProxy = AopUtils.isAopProxy(current);
        while (AopUtils.isAopProxy(current)) {
            Object currentRefObject = AopProxyUtils.getSingletonTarget(current);
            if (currentRefObject == null) {
                break;
            }
            current = currentRefObject;
        }
        try {
            if (Proxy.isProxyClass(current.getClass())) {
                return null;
            }
        } catch (Exception ignore) {
        }
        return null;
//        String mongoSource = findMongoSource(invocation.getMethod(), MongoDS.class);
//        String s = processor.doDetermineDatasource(invocation, mongoSource);
//        return s;
    }

    private String findMongoSource(AnnotatedElement annotatedElement,Class<? extends Annotation> annotation){
        MongoDS mergedAnnotation = AnnotatedElementUtils.findMergedAnnotation(annotatedElement, MongoDS.class);

        return mergedAnnotation.value();
    }

//    @Override
//    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        System.out.println(findKey(proxy));
//        return null;
//    }

}
